﻿#include"XQTimerTaskWidget.h"
#include"XQComboCheckButton.h"
#include"XQAlgorithm.h"
#include"XQRobot.h"
#include"XQAppInfo.h"
#include"XQTimerGroup.h"
#include"XQRobotDing.h"
#include<algorithm>
#include<QComboBox>
#include<QStackedLayout>
#include<QBoxLayout>
#include<QCheckBox>
#include<QLabel>
#include<QTimeEdit>
#include<QLineEdit>
#include<QIntValidator>
#include<QMessageBox>
#include<QDebug>
void XQTimerTaskWidget::init()
{
	setMinimumWidth(800);
	setMinimumHeight(120);
	init_ui();
	init_timerStackWidget();
	init_taskStackWidget();
	m_daySelectComBox_date->hide();
	setCssFile(this,":/XQTimerTaskWidget/style.css");
}

void XQTimerTaskWidget::nextRunTime(int id, QDateTime dataTime)
{
	if (id != m_timerId)
		return;
	m_timerInfo->setText("下一次运行:"+ dataTime.toString("yyyy-MM-dd hh:mm:ss"));
	//qInfo() << dataTime;
}

bool XQTimerTaskWidget::joinTimer(int id)
{
	if (taskName().isEmpty())
	{
		QMessageBox::information(this, "名字", "名字不能为空");
		return false;
	}
	auto timer = timerGroup();
	if (timer == nullptr)
	{
		QMessageBox::information(this, "定时器组", "XQAppInfo::timerGroup()=nullptr,未设置");
		return false;
	}
	if (timerType() == TimerType::date&& timeType() != TimeType::day&&daySelect().isEmpty())
	{
		QMessageBox::information(this, "定时器组", "还未选择天数");
		return false;
	}
	XQTimerTask task;
	std::function<QDateTime(QDateTime)> nextTime = this->nextTime();//下一次时间
	std::function<void()>taskFunc = this->taskFunc();//任务
	if(taskFunc==nullptr)
	{
		QMessageBox::information(this, "任务", "任务还未设置");
		return false;
	}
	std::function<void(XQTimerTask*)>robotPush = this->robotPush(nextTime);//机器人推送
	
	if (timerType() == TimerType::time)
	{
		int msecs = timerTime_time().msecsSinceStartOfDay();
		task.setTimerSec(msecs / 1000);
		task.setRunTime(startDateTime());
	}
	else
	{
		auto time = timerTime_date();
		task.setUpTimeFunc([=](XQTimerTask* task)->QDateTime {
			return nextTime(QDateTime(task->runTime().date(), time)); });
		//qInfo() << startDateTime().secsTo(QDateTime::currentDateTime());
		QDateTime dateTime= startDateTime();
		while (dateTime.secsTo(QDateTime::currentDateTime()) > 60)
		{
			dateTime = nextTime(QDateTime(dateTime.date(), time));
		}
		task.setRunTime(dateTime);
		/*if(startDateTime().secsTo(QDateTime::currentDateTime())<60)
			task.setRunTime(startDateTime());
		else
			task.setRunTime(nextTime(QDateTime(QDateTime::currentDateTime().date(), time)));*/
		/*qInfo() << task.runTime().toString("yyyy-MM-dd hh:mm:ss");*/
	}
	task.setRunCount(runCount());
	task.setTask([=] (XQTimerTask* task){
		//qInfo() << "执行任务";
		robotPush(task);
		taskFunc();
		});
	m_timerId=timer->addTask(task,id);
	return true;
}

std::function<void()> XQTimerTaskWidget::taskFunc() 
{
	std::function<void()> task=nullptr;
	//绑定任务了
	if (taskType() == TaskType::root)
	{
		if (m_taskRootComBox->count() == 0)
		{
			//QMessageBox::information(this, "任务", "当前没有预设的任务");
			return task;
		}
		auto taskGroup = m_taskRootComBox->currentData().value< QMap<QString, std::function<void()>>* >();
		task = (*taskGroup)[m_taskRootComBox->currentText()];
	}
	else if (taskType() == TaskType::user)
	{
		if (taskUser().isEmpty())
		{
			//QMessageBox::information(this, "任务", "任务还未设置");
			return task;
		}
		task = [=] {::system(taskUser().toLocal8Bit().data()); };
	}
	return task;
}

std::function<QDateTime(QDateTime)> XQTimerTaskWidget::nextTime()
{
	std::function<QDateTime(QDateTime)> next = nullptr;
	if (timerType() == TimerType::time)
	{//时间间隔
		int msecs = timerTime_time().msecsSinceStartOfDay();
		next = [=](QDateTime currentDate) {return currentDate.addMSecs(msecs); };
		//task.setTimerSec(msecs / 1000);
	}
	else if (timerType() == TimerType::date)
	{
		auto  days = daySelect();//索引从零开始
		auto time = timerTime_date();
		if (timeType() == TimeType::day)
		{
			next = [=](QDateTime currentDate) {return currentDate.addDays(1); };
		}
		else if (timeType() == TimeType::week)
		{
			next = [=](QDateTime currentDate) {
				auto currentWeek = currentDate.date().dayOfWeek();//
				auto it = std::find_if(days.begin(), days.end(), [=](const int nSel) {return nSel > currentWeek - 1; });
				if (it != days.end())
				{//找到在这个星期
					return currentDate.addDays((*it) + 1 - currentWeek);
				}
				else
				{//下个星期
					return currentDate.addDays(7 - currentWeek + days.front() + 1);
				}
			};
		}
		else if (timeType() == TimeType::month)
		{
			next = [=](QDateTime currentDate) {
				auto currentDay = currentDate.date().day();//当月第几天
				auto maxDay = currentDate.date().daysInMonth();//当月最大天数
				auto it = std::find_if(days.begin(), days.end(), [=](const int nSel) {if (nSel < maxDay)return nSel > currentDay - 1; else return false; });
				if (it != days.end())
				{//找到在这个月 
					return currentDate.addDays((*it) + 1 - currentDay);
				}
				else
				{//下个月
					return currentDate.addDays(maxDay - currentDay + days.front() + 1);
				}
			};
		}
	}
	return next;
}

std::function<void(XQTimerTask*)> XQTimerTaskWidget::robotPush(std::function<QDateTime(QDateTime)> nextTime)
{
	std::function<void(XQTimerTask*)> push;
	//机器人推送
	{
		auto name = taskName();
		auto robot = this->robotSelect();
		auto taskType = int(this->taskType());
		auto rootTask = m_taskRootComBox?m_taskRootComBox->currentText() : QString();
		auto userTask = m_taskUserEdit?m_taskUserEdit->text():QString();
		push = [=](XQTimerTask* task) {
			QString info = "定时器任务:\r\n" + name + "\r\n执行时间:\r\n" + QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
			info = info + "\r\n执行任务:\r\n" + QStringList{"预设", "用户"}[taskType] + "---" + QStringList{rootTask, userTask}[taskType];
			if (task->isCountFinish() || !task->isEnabled())
			{
				info += "\r\n定时器结束!!!!!";
			}
			else
			{
				info = info + "\r\n下次执行时间是:\r\n" + nextTime(QDateTime::currentDateTime()).toString("yyyy-MM-dd hh:mm:ss");
				info = info + "\r\n剩余次数:" + ((task->runCount() == -1) ? "永久" : QString("%1次").arg(task->runCount()));
			}
			if (robot.indexOf(int(RobotType::DingDing)) != -1)
			{
				XQRobotDing* robot = (XQRobotDing*)XQAppInfo::robot(RobotType::DingDing);
				if (robot != nullptr)
				{
					robot->sendText(info);
				}
			}

		};
	}
	return push;
}

QBoxLayout* XQTimerTaskWidget::init_task()
{
	m_enableCheck = new QCheckBox("启用", this);
	m_taskName = new QLineEdit(this);
	m_startDateTime = new QDateTimeEdit(QDateTime::currentDateTime(), this);
	m_countEdit = new QLineEdit(this);
	m_timerInfo = new QLabel(this);
	auto layout = new QBoxLayout(QBoxLayout::LeftToRight);//
	layout->addWidget(m_enableCheck);
	layout->addWidget(m_taskName);
	layout->addWidget(new QLabel("第一次运行时间:"));
	layout->addWidget(m_startDateTime);
	layout->addWidget(new QLabel("运行次数"));
	layout->addWidget(m_countEdit);
	layout->addStretch(1);
	layout->addWidget(m_timerInfo);
	//初始化数据
	m_taskName->setMinimumWidth(100);
	m_taskName->setPlaceholderText("名字");
	m_startDateTime->setDisplayFormat("yyyy-MM-dd HH:mm");
	m_startDateTime->setCalendarPopup(true);
	m_startDateTime->setMinimumWidth(150);

	m_countEdit->setValidator(new QIntValidator(1, INT32_MAX));
	m_countEdit->setPlaceholderText("留空为一直循环");

	//绑定函数 
	connect(m_enableCheck, &QCheckBox::stateChanged,this,&XQTimerTaskWidget::setTaskEnable);
	return layout;
}

QBoxLayout* XQTimerTaskWidget::init_timerType()
{
	m_timerTypeComBox = new QComboBox(this);
	m_timerStackLayout = new QStackedLayout();
	auto layout = new QBoxLayout(QBoxLayout::LeftToRight);//
	layout->addWidget(new QLabel("定时类型:"));
	layout->addWidget(m_timerTypeComBox);
	layout->addLayout(m_timerStackLayout,1);
	
	//初始化数据
	m_timerTypeComBox->addItem("时间",int (TimerType::time));
	m_timerTypeComBox->addItem("日期", int(TimerType::date));
	m_timerTypeComBox->setMinimumWidth(80);
	//绑定的槽函数
	connect(m_timerTypeComBox,&QComboBox::currentIndexChanged, m_timerStackLayout,&QStackedLayout::setCurrentIndex);
	return layout;
}

QBoxLayout* XQTimerTaskWidget::init_taskType()
{
	m_taskTypeComBox = new QComboBox(this);
	m_taskStackLayout= new QStackedLayout();
	m_robot = new XQComboCheckButton(this);
	auto layout = new QBoxLayout(QBoxLayout::LeftToRight);//
	layout->addWidget(new QLabel("任务类型:"));
	layout->addWidget(m_taskTypeComBox);
	layout->addLayout(m_taskStackLayout, 1);
	layout->addWidget(m_robot);
	//初始化数据
	m_taskTypeComBox->addItem("预设", int(TaskType::root));
	m_taskTypeComBox->addItem("用户", int(TaskType::user));
	m_taskTypeComBox->setMinimumWidth(80);

	m_robot->setObjectName("robot");
	m_robot->addItem("钉钉", int(RobotType::DingDing));
	m_robot->setText("推送机器人");
	m_robot->setMinimumWidth(150);
	//绑定的槽函数
	connect(m_taskTypeComBox, &QComboBox::currentIndexChanged, m_taskStackLayout, &QStackedLayout::setCurrentIndex);
	return layout;
}

void XQTimerTaskWidget::init_ui()
{
	auto widget = new QWidget(this);
	auto layout = new QBoxLayout(QBoxLayout::TopToBottom, widget);//
	//layout->setContentsMargins(0, 0, 0, 0);
	layout->addLayout(init_task());
	layout->addLayout(init_timerType());
	layout->addLayout(init_taskType());
	widget->setLayout(layout);
	{
		auto layout = new QBoxLayout(QBoxLayout::TopToBottom, this);//
		layout->setContentsMargins(0, 0, 0, 0);
		layout->addWidget(widget);
		setLayout(layout);
		widget->setObjectName("background");
	}
	m_background = widget;
}

void XQTimerTaskWidget::init_timerStackWidget()
{
	{//时间
		m_timerEdit_time = new QTimeEdit(QTime(0,1,0,0));
		auto widget = new QWidget(this);
		auto layout = new QBoxLayout(QBoxLayout::LeftToRight, widget);//
		layout->setContentsMargins(0, 0, 0, 0);
		layout->addWidget(m_timerEdit_time);
		layout->addWidget(new QLabel("间隔时间(时:分:秒)"));
		layout->addStretch(1);
		widget->setLayout(layout);
		m_timerStackLayout->addWidget(widget);

		//初始化数据
		m_timerEdit_time->setDisplayFormat("HH:mm:ss");
		m_timerEdit_time->setMinimumWidth(100);
		m_timerEdit_time->setButtonSymbols(QAbstractSpinBox::PlusMinus); // 设置按钮为上下箭头

	}
	{//日期
		m_timeTypeComBox_date = new QComboBox(this);
		m_daySelectComBox_date = new XQComboCheckButton(this);
		m_timerEdit_date = new QTimeEdit(QTime(0, 1, 0, 0));
		auto widget = new QWidget(this);
		auto layout = new QBoxLayout(QBoxLayout::LeftToRight, widget);//
		layout->setContentsMargins(0, 0, 0, 0);
		layout->addWidget(m_timeTypeComBox_date);
		layout->addWidget(m_daySelectComBox_date);
		layout->addWidget(m_timerEdit_date);
		layout->addWidget(new QLabel("选中每日(时:分)"));
		layout->addStretch(1);
		widget->setLayout(layout);
		m_timerStackLayout->addWidget(widget);

		//初始化数据
		m_timeTypeComBox_date->addItem("每天",int(TimeType::day));
		m_timeTypeComBox_date->addItem("每周", int(TimeType::week));
		m_timeTypeComBox_date->addItem("每月", int(TimeType::month));
		m_timeTypeComBox_date->setMinimumWidth(80);

		m_daySelectComBox_date->setObjectName("daySelect");
		m_daySelectComBox_date->setText("天数选择");
		m_daySelectComBox_date->setMinimumWidth(120);
		m_daySelectComBox_date->setShowRowCount(7);

		m_timerEdit_date->setDisplayFormat("HH:mm");
		m_timerEdit_date->setMinimumWidth(100);
		m_timerEdit_date->setButtonSymbols(QAbstractSpinBox::PlusMinus); // 设置按钮为上下箭头

		//绑定槽函数
		connect(m_timeTypeComBox_date, &QComboBox::currentIndexChanged, [this](int index) {timeTypeComBox_dateChanged(index);
		if (TimeType(m_timeTypeComBox_date->currentData().toInt()) == TimeType::day)
			m_daySelectComBox_date->hide();
		else
			m_daySelectComBox_date->show();
			});
		connect(m_daySelectComBox_date,&QPushButton::pressed, m_daySelectComBox_date,&XQComboCheckButton::showView);
	}
}

void XQTimerTaskWidget::init_taskStackWidget()
{
	{//预设的
		auto widget = new QWidget(this);
		m_taskRootComBox = new QComboBox(widget);
		auto layout = new QBoxLayout(QBoxLayout::LeftToRight, widget);//
		layout->setContentsMargins(0, 0, 0, 0);
		layout->addWidget(m_taskRootComBox);
		widget->setLayout(layout);
		m_taskStackLayout->addWidget(widget);
	}
	{//用户的
		auto widget = new QWidget(this);
		m_taskUserEdit = new QLineEdit(widget);
		auto layout = new QBoxLayout(QBoxLayout::LeftToRight, widget);//
		layout->setContentsMargins(0, 0, 0, 0);
		layout->addWidget(m_taskUserEdit);
		widget->setLayout(layout);
		m_taskStackLayout->addWidget(widget);
		//参数设置
		m_taskUserEdit->setPlaceholderText("CMD 命令启动任务");
	}
}

void XQTimerTaskWidget::timeTypeComBox_dateChanged(int index)
{
	m_daySelectComBox_date->clear();
	switch (TimeType(index))
	{
	case TimeType::day:
		break;
	case TimeType::week:
	{
		for (size_t i = 0; i < 7; i++)
		{
			m_daySelectComBox_date->addItem(QString("星期%1").arg(QStringList{"一","二","三","四","五","六","日"}[i]));
		}
	}
		break;
	case TimeType::month:
	{
		for (size_t i = 0; i < 31; i++)
		{
			m_daySelectComBox_date->addItem(QString("%1号").arg(i+1));
		}
	}
		break;
	default:
		break;
	}
}

void XQTimerTaskWidget::mousePressEvent(QMouseEvent* ev)
{
}
